package view;

import java.io.IOException;
import java.util.Scanner;

import controller.AfdController;
import controller.BrzozowskiController;
import controller.ComputeWordController;
import controller.KleeneController;

public class Main {
	/*
	 * Lucas Simões de Sousa Arnaud Dre:110092791
	 * Victor Lima Campos Dre:110092539
	 */
	
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		AfdController controller = AfdController.getInstance();
		int key;
		Scanner scan =  new Scanner(System.in);
		
		initAfd(controller, scan);
		boolean exit = false;	
		while(!exit){
			showMenu();
			
			//Cria variável de controle
			key = scan.nextInt();
			scan.nextLine();
			
			//Seleciona qual programa usar
			switch (key) {
			case 1:
				computeWord(controller, scan);
				break;
			case 2:
				System.out.println(BrzozowskiController.getInstance().brzozowski());
				break;
			case 3:
				System.out.println(KleeneController.getInstance().kleene());
				break;
			case 4:
				createAfd(controller, scan);
				break;
			case 5:
				controller.saveAfdIntoTheFile();
				System.out.println("Afd salvo com sucesso!");
				break;
			case 6:
				controller.loadAfdFromFile();
				break;
			//Easter Egg
			case 42:
				System.out.println("The answer to life the universe and everything!");
				break;
			default:
				exit = true;
				break;
			}
		}
	}

	static void initAfd(AfdController controller, Scanner scan)
			throws IOException, ClassNotFoundException {
		int key;
		System.out.println("1 - Criar novo afd");
		System.out.println("2 - Carregar afd do arquivo");
		key = scan.nextInt();
		scan.nextLine();
		
		//Seleciona qual programa usar
		switch (key) {
			case 1:
				createAfd(controller, scan);
				break;
			case 2:
				controller.loadAfdFromFile();
				break;
		}
		if(controller.getAfd() == null){
			System.out.println("Desculpe não foi possível carregar o afd do arquivo.");
			createAfd(controller, scan);
		}
	}

	private static void computeWord(AfdController controller, Scanner scan) {		
		String word = getWord(scan);
		System.out.println(ComputeWordController.getInstance().computeWord(word));
	}

	private static void createAfd(AfdController controller, Scanner scan) {
		String states = getStates(scan);
		int isTheFirstStateFinal = isTheFirstStateFinal(scan);
		int numFinalStates = getNumberOfFinalStates(scan);
		scan.nextLine(); // scape \n
		String symbols = getSymbols(scan);
		String transitions = getTransitions(scan);
		
		controller.saveAfd(states, numFinalStates, symbols, transitions, isTheFirstStateFinal);
	}

	private static String getWord(Scanner scan) {
		System.out.println("Entre com a palavra");
		System.out.println("Uma palavra só pode ser formada por simbolos do alfabeto");
		String word = scan.next();
		return word;
	}

	private static String getTransitions(Scanner scan) {
		System.out.println("Entre com as transicoes separados por espaço");
		System.out.println("Uma transicao é do formato ExS-E");
		System.out.println("Onde S é um simbolo e E um estado");
		String transitions = scan.nextLine();
		return transitions;
	}

	private static String getSymbols(Scanner scan) {
		System.out.println("Entre com os simbolos separados por espaço");
		System.out.println("Um simbolo é qualquer letra do alfabeto menos o x mais os números de 1 a 9");
		System.out.println("Para aumentar a quantidade de simbolos, A é diferente de a");
		String symbols = scan.nextLine();
		return symbols;
	}

	private static int getNumberOfFinalStates(Scanner scan) {
		System.out.println("Entre com a quantidade de estados finais.");
		int numFinalStates = scan.nextInt();
		return numFinalStates;
	}

	private static int isTheFirstStateFinal(Scanner scan) {
		System.out.println("O primeiro estado será o inicial e os n próximos os finais.");
		System.out.println("Você deseja que o primeiro estado também seja final?");
		System.out.println("Digite 1 para sim e 0 para não.");
		int firstStateIsFinal = scan.nextInt();
		return firstStateIsFinal;
	}

	private static String getStates(Scanner scan) {
		System.out.println("Entre com os estados separados por espaço");
		System.out.println("Um estado é alphanumérico com números de 1 a 9.");
		System.out.println("Para aumentar a quantidade de estados, A é diferente de a");
		String states = scan.nextLine();
		return states;
	}

	private static void showMenu() {
		//Monta o menu de seleção do programa
		System.out.println("Selecione uma opção:");
		System.out.println("1 - Computação do AFD");
		System.out.println("2 - Algoritmo de Brzozowski");
		System.out.println("3 - Algoritmo de Kleene");
		System.out.println("4 - Novo Afd");
		System.out.println("5 - Salvar Afd");
		System.out.println("6 - Carregar Afd");
		System.out.println("Outro - Sair");
	}
}
